﻿using System;
using System.IO;
using DasherBci;

namespace ConsoleView
{

    /*
    This was the original interface to the program but is now obsolete (replaced by WpfView).
    */

    public class Program
    {
        private readonly static EmotivController _emotivController = new EmotivController();
        private readonly static DasherController _dasherController = new DasherController();

        private static void Main()
        {
            Console.WriteLine("~ Dasher BCI ~");
            _emotivController.Connect();

            while (true)
            {
                Console.WriteLine("OPTIONS:");
                Console.WriteLine("[L]oad user | [S]ave user | [T]rain | [B]egin typing | [Q]uit");
                switch (GetOption())
                {
                    case 'L':
                        HandleLoadExistingUserOption();
                        break;
                    case 'S':
                        HandleSaveCurrentUserOption();
                        break;
                    case 'T':
                        HandleTrainingOption();
                        break;
                    case 'B':
                        HandleBeginTypingOption();
                        break;
                    case 'Q':
                        return;
                    default:
                        Console.WriteLine("Unrecognised option!");
                        break;
                }
            }
        }

        private static char GetOption()
        {
            try
            {
                return (Console.ReadLine() ?? "")[0];
            }
            catch (IndexOutOfRangeException) // occurs when nothing is entered
            {
                return char.MinValue;
            }
        }

        private static void HandleTrainingOption()
        {
            Console.WriteLine("TRAINING:");
            Console.WriteLine("Enter training action ([N]eutral, [U]p or [D]own):");
            TrainedAction actionToTrain;
            switch (GetOption())
            {
                case 'N':
                    actionToTrain = TrainedAction.Neutral;
                    break;
                case 'U':
                    actionToTrain = TrainedAction.Up;
                    break;
                case 'D':
                    actionToTrain = TrainedAction.Down;
                    break;
                default:
                    Console.WriteLine("Unrecognised option!");
                    return;
            }
            Console.WriteLine("Think about \"{0}\"! 8 seconds' training begins as soon as a key is pressed...",
                              Enum.GetName(typeof(TrainedAction), actionToTrain));
            Console.ReadKey(true);
            TrainingResult result = _emotivController.AttemptTraining(actionToTrain);
            Console.Beep();

            if (result == TrainingResult.Failure)
            {
                Console.WriteLine("Training failed. Verify contact quality.");
            }
            else if (result == TrainingResult.Success)
            {
                Console.WriteLine("Training succeeded.");
            }
        }

        private static void HandleBeginTypingOption()
        {
            Console.WriteLine("TYPING:");
            Console.WriteLine("Now controlling Dasher. Press any key to end.");
            _emotivController.NewEegData += _emotivController_NewEegData;
            _dasherController.UpdateVector(_dasherController.VectorOrigin);
            _emotivController.BeginReadingData();
            Console.ReadKey(true);
            _emotivController.NewEegData -= _emotivController_NewEegData;
            _emotivController.EndReadingData();
            Console.WriteLine("Finished typing.");
        }

        private static void _emotivController_NewEegData(object sender, EegDataEventArgs e)
        {
            CoordinatePair coordinates = EegCoordinateCalculator.CalculateCoordinates(e.Action, e.ActionPower, _dasherController.CurrentPosition);
            _dasherController.UpdateVector(coordinates);
        }

        private static void HandleLoadExistingUserOption()
        {
            Console.WriteLine("LOAD EXISTING USER:");
            Console.WriteLine("Enter full filepath:");
            string filepath = Console.ReadLine() ?? "";
            _emotivController.LoadProfile(filepath);
            Console.WriteLine("User \"{0}\" loaded.", Path.GetFileName(filepath));
        }

        private static void HandleSaveCurrentUserOption()
        {
            Console.WriteLine("SAVE CURRENT USER:");
            Console.WriteLine("Enter full filepath:");
            string filepath = Console.ReadLine() ?? "";
            _emotivController.SaveProfile(filepath);
            Console.WriteLine("User saved.");
        }
    }
}
